#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>

// 日志记录函数
void log_event(const char *event)
{
    FILE *log_file = fopen("./thread_access.log", "a");
    if (log_file)
    {
        fprintf(log_file, "%s\n", event);
        fclose(log_file);
    }
}

// 确保文件存在
void ensure_file_exists(const char *filename)
{
    struct stat buffer;
    if (stat(filename, &buffer) != 0)
    { // 文件不存在
        int fd = open(filename, O_CREAT | O_WRONLY, 0644);
        printf("11111111");
        if (fd == -1)
        {
            perror("Failed to create file");
            exit(EXIT_FAILURE);
        }
        close(fd);
        printf("Created missing file: %s\n", filename);
    }
}

// 模拟文件访问
void access_file(const char *filename, const char *authorized_file, const char *thread_name)
{
    ensure_file_exists(filename);

    if (strcmp(filename, authorized_file) != 0)
    {
        char log_msg[128];
        snprintf(log_msg, sizeof(log_msg), "[%s] Unauthorized access attempt to %s", thread_name, filename);
        log_event(log_msg);
        printf("[%s] Access to %s denied.\n", thread_name, filename);
        return;
    }

    int fd = open(filename, O_RDONLY);
    if (fd == -1)
    {
        perror("open");
        char log_msg[128];
        snprintf(log_msg, sizeof(log_msg), "[%s] Failed to access %s: %s", thread_name, filename, strerror(errno));
        log_event(log_msg);
    }
    else
    {
        char log_msg[128];
        snprintf(log_msg, sizeof(log_msg), "[%s] Accessed %s successfully", thread_name, filename);
        log_event(log_msg);
        printf("[%s] Accessed %s successfully.\n", thread_name, filename);
        close(fd);
    }
}

// 线程函数 - 线程 1
void *thread_func1(void *arg)
{
    const char *authorized_file = "./a.txt";
    const char *thread_name = "Thread 1";

    // 模拟文件访问
    access_file("./a.txt", authorized_file, thread_name);
    access_file("./b.txt", authorized_file, thread_name);

    // 模拟与线程 2 的通信
    int *pipe_fd = (int *) arg;
    const char *msg = "Message from Thread 1 to Thread 2";
    write(pipe_fd[1], msg, strlen(msg) + 1);

    char log_msg[128];
    snprintf(log_msg, sizeof(log_msg), "[%s] Sent message to Thread 2", thread_name);
    log_event(log_msg);

    return NULL;
}

// 线程函数 - 线程 2
void *thread_func2(void *arg)
{
    const char *authorized_file = "./b.txt";
    const char *thread_name = "Thread 2";

    // 模拟文件访问
    access_file("./b.txt", authorized_file, thread_name);
    access_file("./c.txt", authorized_file, thread_name);

    // 模拟接收线程 1 的消息
    int *pipe_fd = (int *) arg;
    char buffer[128];
    read(pipe_fd[0], buffer, sizeof(buffer));

    char log_msg[128];
    snprintf(log_msg, sizeof(log_msg), "[%s] Received message: %s", thread_name, buffer);
    log_event(log_msg);

    return NULL;
}

// 线程函数 - 线程 3
void *thread_func3(void *arg)
{
    const char *authorized_file = "./c.txt";
    const char *thread_name = "Thread 3";

    // 模拟文件访问
    access_file("./c.txt", authorized_file, thread_name);
    access_file("./a.txt", authorized_file, thread_name);

    return NULL;
}

int main()
{
    // 创建日志文件
    FILE *log_file = fopen("./thread_access.log", "w");
    if (log_file) fclose(log_file);

    pthread_t t1, t2, t3;
    int pipe_fd[2];

    // 创建管道用于线程间通信
    if (pipe(pipe_fd) == -1)
    {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    // 创建线程
    pthread_create(&t1, NULL, thread_func1, pipe_fd);
    pthread_create(&t2, NULL, thread_func2, pipe_fd);
    pthread_create(&t3, NULL, thread_func3, NULL);

    // 等待线程结束
    pthread_join(t1, NULL);
    pthread_join(t2, NULL);
    pthread_join(t3, NULL);

    // 关闭管道
    close(pipe_fd[0]);
    close(pipe_fd[1]);

    printf("All threads finished. Check thread_access.log for details.\n");
    return 0;
}
